package com.compomics.prioritizer.general.gui;

import com.compomics.prioritizer.db.accessors.*;
import com.compomics.prioritizer.db.accessors.Label;
import com.compomics.prioritizer.general.PrioritizerSingelton;

import javax.swing.*;
import javax.swing.border.TitledBorder;
import java.sql.Connection;
import java.sql.SQLException;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.awt.event.ItemListener;
import java.awt.event.ItemEvent;
import java.awt.*;
import java.util.Collections;
import java.util.HashMap;
import java.util.Vector;

/**
 * Created by IntelliJ IDEA.
 * User: Niklaas Colaert
 * Date: 31-okt-2008
 * Time: 9:40:52
 * To change this template use File | Settings | File Templates.
 */
public class CreateProjectGui extends JFrame {
    private JTextField textField1;
    private JTextArea textArea1;
    private JComboBox cmbInstrument;
    private JButton createProjectButton;
    private JButton cancelButton;
    private JPanel projectParamPanel;
    private JComboBox cmbUser;
    private JPanel jpanContent;
    private JComboBox cmbProtocol;
    private JComboBox cmbModification;
    private JButton addButton;
    private JButton addButton1;
    private JList listFixMod;
    private JList listVarMod;
    private JComboBox cmbTaxonomy;
    private JComboBox cmbLabel;
    private JComboBox cmbProjectType;

    //the connection
    private Connection iConnPriority;
    //the Instruments
    private Instrument[] iInstruments;
    //the Instruments
    private User[] iUsers;
    //the Protocols
    private Protocol[] iProtocols;
    //the Modifications
    private Modification[] iModifications;
    //the fixed Modifications
    private Vector fixedMods;
    //the variable Modifications
    private Vector varMods;
    //the taxonomies
    private Taxonomy[] iTaxonomies;
    //the labels
    private Label[] iLabels;
    //the ProjectTypes
    private ProjectType[] iProjectTypes;

    private PrioritizerSingelton iPrioritizerSingelton;

    public CreateProjectGui(Connection aConn, User aUser) {
        super("Create a new project");
        this.iConnPriority = aConn;
        iPrioritizerSingelton = PrioritizerSingelton.getInstance();
        $$$setupUI$$$();
        createProjectButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                createProject();
            }
        });
        Dimension screen = Toolkit.getDefaultToolkit().getScreenSize();
        this.setLocation((screen.width / 5), (screen.height / 10));
        setContentPane(jpanContent);
        this.setSize(600, 600);
        this.setVisible(true);
        addButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                addFixedMod();
            }
        });
        addButton1.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                addVarMod();
            }
        });
        cmbProtocol.addItemListener(new ItemListener() {
            public void itemStateChanged(ItemEvent e) {
                if (e.getStateChange() == ItemEvent.SELECTED) {
                    protocolChanged((Protocol) e.getItem());
                }
            }
        });
    }

    public void addFixedMod() {
        Modification addMod = (Modification) cmbModification.getSelectedItem();
        fixedMods.add(addMod);
        listFixMod.updateUI();
    }

    public void storeModifications(long aProjectId) {
        //store fixed modifications
        for (int f = 0; f < fixedMods.size(); f++) {
            HashMap hm = new HashMap(3);
            hm.put(Modification_link.PROJECT, 1);
            hm.put(Modification_link.PROTOCOL, 0);
            //type is 1 for fixed
            hm.put(Modification_link.TYPE, 1);
            hm.put(Modification_link.L_MODIFICATIONID, ((Modification) fixedMods.get(f)).getModificationid());
            hm.put(Modification_link.L_LINKID, aProjectId);

            Modification_link lModification_link = new Modification_link(hm);
            try {
                lModification_link.persist(iConnPriority);
            } catch (SQLException e) {
                JOptionPane.showMessageDialog(this, new String[]{"Unable to store modifications for this project:  ", e.getMessage()}, "Error!", JOptionPane.ERROR_MESSAGE);
            }
        }

        //store variable modifications
        for (int f = 0; f < varMods.size(); f++) {
            HashMap hm = new HashMap(3);
            hm.put(Modification_link.PROJECT, 1);
            hm.put(Modification_link.PROTOCOL, 0);
            //type is 0 for variable
            hm.put(Modification_link.TYPE, 0);
            hm.put(Modification_link.L_MODIFICATIONID, ((Modification) varMods.get(f)).getModificationid());
            hm.put(Modification_link.L_LINKID, aProjectId);


            Modification_link lModification_link = new Modification_link(hm);
            try {
                lModification_link.persist(iConnPriority);
            } catch (SQLException e) {
                JOptionPane.showMessageDialog(this, new String[]{"Unable to store modifications for this project:  ", e.getMessage()}, "Error!", JOptionPane.ERROR_MESSAGE);
            }
        }


    }

    public void protocolChanged(Protocol aProtocol) {
        if (aProtocol.getName().equalsIgnoreCase("User specific protocol")) {
            addButton.setEnabled(true);
            addButton1.setEnabled(true);
        } else {
            addButton.setEnabled(false);
            addButton1.setEnabled(false);
            fixedMods.removeAllElements();
            varMods.removeAllElements();
            Modification[] fix = new Modification[0];
            Modification[] var = new Modification[0];
            try {
                fix = Modification_link.getProtocolFixedModification_links(iConnPriority, aProtocol.getProtocolid());
                var = Modification_link.getProtocolVariableModification_links(iConnPriority, aProtocol.getProtocolid());
            } catch (SQLException e) {
                JOptionPane.showMessageDialog(this, new String[]{"Unable to load modificatoins for protocol:  ", e.getMessage()}, "Error!", JOptionPane.ERROR_MESSAGE);
            }

            for (int f = 0; f < fix.length; f++) {
                fixedMods.add(fix[f]);
            }
            for (int f = 0; f < var.length; f++) {
                varMods.add(var[f]);
            }
            listFixMod.updateUI();
            listVarMod.updateUI();
        }
    }

    public void addVarMod() {
        Modification addMod = (Modification) cmbModification.getSelectedItem();
        varMods.add(addMod);
        listVarMod.updateUI();
    }

    public void gatherData() {
        this.findProjectTypes();
        this.findInstruments();
        this.findUsers();
        this.findModifications();
        this.findProtocols();
        this.findTaxonomies();
        this.findLabels();
    }

    /**
     * This method collects all instruments.
     * It fills the 'iInstruments' cache.
     */
    private void findInstruments() {
        try {
            iInstruments = Instrument.getAllInstruments(iConnPriority);
        } catch (SQLException sqle) {
            JOptionPane.showMessageDialog(this, new String[]{"Unable to find instruments:  ", sqle.getMessage()}, "Error!", JOptionPane.ERROR_MESSAGE);
        }
    }


    /**
     * This method collects all taxonomies.
     * It fills the 'iTaxonomies' cache.
     */
    private void findTaxonomies() {
        try {
            iTaxonomies = Taxonomy.getAllTaxonomys(iConnPriority);
        } catch (SQLException sqle) {
            JOptionPane.showMessageDialog(this, new String[]{"Unable to find taxonomy:  ", sqle.getMessage()}, "Error!", JOptionPane.ERROR_MESSAGE);
        }
    }


    /**
     * This method collects all labels.
     * It fills the 'iLabels' cache.
     */
    private void findLabels() {
        try {
            iLabels = Label.getAllLabels(iConnPriority);
        } catch (SQLException sqle) {
            JOptionPane.showMessageDialog(this, new String[]{"Unable to find labels:  ", sqle.getMessage()}, "Error!", JOptionPane.ERROR_MESSAGE);
        }
    }

    /**
     * This method collects all users.
     * It fills the 'iUsers' cache.
     */
    private void findUsers() {
        try {
            iUsers = User.getAllUsers(iConnPriority);
        } catch (SQLException sqle) {
            JOptionPane.showMessageDialog(this, new String[]{"Unable to find users:  ", sqle.getMessage()}, "Error!", JOptionPane.ERROR_MESSAGE);
        }
    }

    /**
     * This method collects all project types.
     * It fills the 'iProjectTypes' cache.
     */
    private void findProjectTypes() {
        try {
            iProjectTypes = (ProjectType[]) ProjectType.retrieveAllEntries(iConnPriority).toArray();
        } catch (SQLException sqle) {
            JOptionPane.showMessageDialog(this, new String[]{"Unable to find project types:  ", sqle.getMessage()}, "Error!", JOptionPane.ERROR_MESSAGE);
        }
    }

    /**
     * This method collects all protocols.
     * It fills the 'iProtocol' cache.
     */
    private void findProtocols() {
        try {
            iProtocols = Protocol.getAllProtocols(iConnPriority);
        } catch (SQLException sqle) {
            JOptionPane.showMessageDialog(this, new String[]{"Unable to find protocols:  ", sqle.getMessage()}, "Error!", JOptionPane.ERROR_MESSAGE);
        }
    }

    /**
     * This method collects all modifications.
     * It fills the 'iModifications' cache.
     */
    private void findModifications() {
        try {
            iModifications = Modification.getAllModifications(iConnPriority);
        } catch (SQLException sqle) {
            JOptionPane.showMessageDialog(this, new String[]{"Unable to find modifications:  ", sqle.getMessage()}, "Error!", JOptionPane.ERROR_MESSAGE);
        }
    }

    /**
     * This method gets all data from the GUI components and creates a project.
     */
    public void createProject() {
        HashMap hm = null;
        // Get the data in the textfields.
        String lTitle = textField1.getText().trim();
        Instrument lInstrument = (Instrument) cmbInstrument.getSelectedItem();
        User lUser = (User) cmbUser.getSelectedItem();
        String lDescription = textArea1.getText();

        // See if the not-NULL fields are filled out.
        if (lTitle.equals("")) {
            JOptionPane.showMessageDialog(this, "Project title must be filled out!", "Title has to be filled out!", JOptionPane.WARNING_MESSAGE);
            textField1.requestFocus();
        } else {

            Protocol prot = (Protocol) cmbProtocol.getSelectedItem();
            Label label = (Label) cmbLabel.getSelectedItem();
            Taxonomy tax = (Taxonomy) cmbTaxonomy.getSelectedItem();
            // Creation of the param HashMap.
            hm = new HashMap(3);
            hm.put(Project.NAME, lTitle);
            hm.put(Project.DESCRIPTION, lDescription);
            hm.put(Project.L_INSTRUMENTID_PROPOSED, lInstrument.getInstrumentid());
            hm.put(Project.L_USERID, lUser.getUserid());
            hm.put(Project.L_PROTOCOLID, prot.getProtocolid());
            hm.put(Project.L_TAXONOMYID, tax.getTaxonomyid());
            hm.put(Project.L_LABELID, label.getLabelid());


            Project lProject = new Project(hm);
            try {
                lProject.createNewProject(iConnPriority);
                Protocol aProtocol = (Protocol) cmbProtocol.getSelectedItem();
                if (aProtocol.getName().equalsIgnoreCase("User specific protocol")) {
                    Object[] keys = lProject.getGeneratedKeys();
                    this.storeModifications(Long.valueOf(keys[0].toString()));
                }
                MailSendingPanel lMail = new MailSendingPanel();
                iPrioritizerSingelton.addMailSendingPanel(lMail);
                lMail.newProject(iConnPriority, lProject);
            } catch (SQLException e) {
                JOptionPane.showMessageDialog(this, "Project could not be stored!\n" + e.getMessage(), "ERROR", JOptionPane.WARNING_MESSAGE);
                return;
            }
            JOptionPane.showMessageDialog(this, "You succesfully created a project", "Project created", JOptionPane.INFORMATION_MESSAGE);
            this.close();
        }
    }

    private void createUIComponents() {
        this.gatherData();
        cmbInstrument = new JComboBox(iInstruments);
        cmbUser = new JComboBox(iUsers);
        cmbProjectType = new JComboBox(iProjectTypes);
        cmbModification = new JComboBox(iModifications);
        cmbTaxonomy = new JComboBox(iTaxonomies);
        cmbProtocol = new JComboBox(iProtocols);
        varMods = new Vector();
        fixedMods = new Vector();
        listVarMod = new JList(varMods);
        listFixMod = new JList(fixedMods);
        cmbLabel = new JComboBox(iLabels);
    }

    public void close() {
        this.setVisible(false);
    }

    /**
     * Method generated by IntelliJ IDEA GUI Designer
     * >>> IMPORTANT!! <<<
     * DO NOT edit this method OR call it in your code!
     *
     * @noinspection ALL
     */
    private void $$$setupUI$$$() {
        createUIComponents();
        jpanContent = new JPanel();
        jpanContent.setLayout(new GridBagLayout());
        projectParamPanel = new JPanel();
        projectParamPanel.setLayout(new GridBagLayout());
        GridBagConstraints gbc;
        gbc = new GridBagConstraints();
        gbc.gridx = 0;
        gbc.gridy = 0;
        gbc.gridwidth = 10;
        gbc.weightx = 1.0;
        gbc.weighty = 1.0;
        gbc.fill = GridBagConstraints.BOTH;
        jpanContent.add(projectParamPanel, gbc);
        projectParamPanel.setBorder(BorderFactory.createTitledBorder(null, "Project properties", TitledBorder.DEFAULT_JUSTIFICATION, TitledBorder.ABOVE_TOP, new Font(projectParamPanel.getFont().getName(), projectParamPanel.getFont().getStyle(), 16), new Color(-16777216)));
        gbc = new GridBagConstraints();
        gbc.gridx = 1;
        gbc.gridy = 2;
        gbc.gridwidth = 5;
        gbc.anchor = GridBagConstraints.WEST;
        gbc.fill = GridBagConstraints.HORIZONTAL;
        gbc.insets = new Insets(5, 0, 5, 0);
        projectParamPanel.add(cmbInstrument, gbc);
        final JLabel label1 = new JLabel();
        label1.setText("Proposed instrument:");
        gbc = new GridBagConstraints();
        gbc.gridx = 0;
        gbc.gridy = 2;
        gbc.anchor = GridBagConstraints.WEST;
        gbc.insets = new Insets(0, 5, 0, 5);
        projectParamPanel.add(label1, gbc);
        final JLabel label2 = new JLabel();
        label2.setText("Project description:");
        gbc = new GridBagConstraints();
        gbc.gridx = 0;
        gbc.gridy = 3;
        gbc.anchor = GridBagConstraints.WEST;
        gbc.insets = new Insets(0, 5, 0, 5);
        projectParamPanel.add(label2, gbc);
        final JLabel label3 = new JLabel();
        label3.setText("Project name:");
        gbc = new GridBagConstraints();
        gbc.gridx = 0;
        gbc.gridy = 0;
        gbc.anchor = GridBagConstraints.WEST;
        gbc.insets = new Insets(0, 5, 0, 5);
        projectParamPanel.add(label3, gbc);
        textField1 = new JTextField();
        gbc = new GridBagConstraints();
        gbc.gridx = 1;
        gbc.gridy = 0;
        gbc.gridwidth = 5;
        gbc.weightx = 1.0;
        gbc.anchor = GridBagConstraints.WEST;
        gbc.fill = GridBagConstraints.HORIZONTAL;
        gbc.insets = new Insets(5, 0, 5, 0);
        projectParamPanel.add(textField1, gbc);
        gbc = new GridBagConstraints();
        gbc.gridx = 4;
        gbc.gridy = 4;
        gbc.gridwidth = 2;
        gbc.anchor = GridBagConstraints.WEST;
        gbc.fill = GridBagConstraints.HORIZONTAL;
        gbc.insets = new Insets(5, 0, 5, 0);
        projectParamPanel.add(cmbUser, gbc);
        final JLabel label4 = new JLabel();
        label4.setText("Select a user:");
        gbc = new GridBagConstraints();
        gbc.gridx = 0;
        gbc.gridy = 4;
        gbc.anchor = GridBagConstraints.WEST;
        gbc.insets = new Insets(0, 5, 0, 5);
        projectParamPanel.add(label4, gbc);
        final JScrollPane scrollPane1 = new JScrollPane();
        gbc = new GridBagConstraints();
        gbc.gridx = 4;
        gbc.gridy = 3;
        gbc.gridwidth = 2;
        gbc.weighty = 1.0;
        gbc.fill = GridBagConstraints.BOTH;
        gbc.insets = new Insets(5, 0, 5, 0);
        projectParamPanel.add(scrollPane1, gbc);
        textArea1 = new JTextArea();
        textArea1.setRows(10);
        scrollPane1.setViewportView(textArea1);
        final JLabel label5 = new JLabel();
        label5.setText("Select a protocol:");
        gbc = new GridBagConstraints();
        gbc.gridx = 0;
        gbc.gridy = 6;
        gbc.anchor = GridBagConstraints.WEST;
        gbc.insets = new Insets(0, 5, 0, 5);
        projectParamPanel.add(label5, gbc);
        gbc = new GridBagConstraints();
        gbc.gridx = 4;
        gbc.gridy = 6;
        gbc.gridwidth = 2;
        gbc.anchor = GridBagConstraints.WEST;
        gbc.fill = GridBagConstraints.HORIZONTAL;
        gbc.insets = new Insets(5, 0, 5, 0);
        projectParamPanel.add(cmbProtocol, gbc);
        final JLabel label6 = new JLabel();
        label6.setText("Modifications:");
        gbc = new GridBagConstraints();
        gbc.gridx = 0;
        gbc.gridy = 8;
        gbc.anchor = GridBagConstraints.WEST;
        gbc.insets = new Insets(0, 5, 0, 5);
        projectParamPanel.add(label6, gbc);
        final JLabel label7 = new JLabel();
        label7.setText("Variable modifications");
        gbc = new GridBagConstraints();
        gbc.gridx = 5;
        gbc.gridy = 9;
        gbc.insets = new Insets(5, 0, 5, 0);
        projectParamPanel.add(label7, gbc);
        final JLabel label8 = new JLabel();
        label8.setText("Fixed modifications");
        gbc = new GridBagConstraints();
        gbc.gridx = 4;
        gbc.gridy = 9;
        gbc.insets = new Insets(5, 0, 5, 0);
        projectParamPanel.add(label8, gbc);
        addButton = new JButton();
        addButton.setText("Add");
        gbc = new GridBagConstraints();
        gbc.gridx = 4;
        gbc.gridy = 10;
        gbc.fill = GridBagConstraints.HORIZONTAL;
        gbc.insets = new Insets(5, 5, 5, 5);
        projectParamPanel.add(addButton, gbc);
        addButton1 = new JButton();
        addButton1.setText("Add");
        gbc = new GridBagConstraints();
        gbc.gridx = 5;
        gbc.gridy = 10;
        gbc.fill = GridBagConstraints.HORIZONTAL;
        gbc.insets = new Insets(5, 5, 5, 5);
        projectParamPanel.add(addButton1, gbc);
        final JScrollPane scrollPane2 = new JScrollPane();
        gbc = new GridBagConstraints();
        gbc.gridx = 4;
        gbc.gridy = 11;
        gbc.weightx = 1.0;
        gbc.weighty = 1.0;
        gbc.fill = GridBagConstraints.BOTH;
        gbc.insets = new Insets(0, 5, 0, 5);
        projectParamPanel.add(scrollPane2, gbc);
        scrollPane2.setViewportView(listFixMod);
        final JScrollPane scrollPane3 = new JScrollPane();
        gbc = new GridBagConstraints();
        gbc.gridx = 5;
        gbc.gridy = 11;
        gbc.weightx = 1.0;
        gbc.weighty = 1.0;
        gbc.fill = GridBagConstraints.BOTH;
        gbc.insets = new Insets(0, 5, 0, 5);
        projectParamPanel.add(scrollPane3, gbc);
        scrollPane3.setViewportView(listVarMod);
        gbc = new GridBagConstraints();
        gbc.gridx = 4;
        gbc.gridy = 8;
        gbc.gridwidth = 2;
        gbc.anchor = GridBagConstraints.WEST;
        gbc.fill = GridBagConstraints.HORIZONTAL;
        gbc.insets = new Insets(5, 0, 5, 0);
        projectParamPanel.add(cmbModification, gbc);
        final JLabel label9 = new JLabel();
        label9.setText("Taxonomy:");
        gbc = new GridBagConstraints();
        gbc.gridx = 0;
        gbc.gridy = 5;
        gbc.anchor = GridBagConstraints.WEST;
        gbc.insets = new Insets(0, 5, 0, 5);
        projectParamPanel.add(label9, gbc);
        gbc = new GridBagConstraints();
        gbc.gridx = 4;
        gbc.gridy = 5;
        gbc.gridwidth = 2;
        gbc.anchor = GridBagConstraints.WEST;
        gbc.fill = GridBagConstraints.HORIZONTAL;
        gbc.insets = new Insets(5, 0, 5, 0);
        projectParamPanel.add(cmbTaxonomy, gbc);
        final JLabel label10 = new JLabel();
        label10.setText("Label:");
        gbc = new GridBagConstraints();
        gbc.gridx = 0;
        gbc.gridy = 7;
        gbc.anchor = GridBagConstraints.WEST;
        gbc.insets = new Insets(0, 5, 0, 5);
        projectParamPanel.add(label10, gbc);
        gbc = new GridBagConstraints();
        gbc.gridx = 4;
        gbc.gridy = 7;
        gbc.gridwidth = 2;
        gbc.anchor = GridBagConstraints.WEST;
        gbc.fill = GridBagConstraints.HORIZONTAL;
        gbc.insets = new Insets(5, 0, 5, 0);
        projectParamPanel.add(cmbLabel, gbc);
        final JLabel label11 = new JLabel();
        label11.setText("Project type:");
        gbc = new GridBagConstraints();
        gbc.gridx = 0;
        gbc.gridy = 1;
        gbc.anchor = GridBagConstraints.WEST;
        gbc.insets = new Insets(5, 5, 5, 5);
        projectParamPanel.add(label11, gbc);
        gbc = new GridBagConstraints();
        gbc.gridx = 4;
        gbc.gridy = 1;
        gbc.gridwidth = 2;
        gbc.anchor = GridBagConstraints.WEST;
        gbc.fill = GridBagConstraints.HORIZONTAL;
        gbc.insets = new Insets(5, 0, 5, 0);
        projectParamPanel.add(cmbProjectType, gbc);
        createProjectButton = new JButton();
        createProjectButton.setText("Create project");
        gbc = new GridBagConstraints();
        gbc.gridx = 8;
        gbc.gridy = 1;
        gbc.weightx = 1.0;
        gbc.fill = GridBagConstraints.HORIZONTAL;
        gbc.insets = new Insets(5, 5, 5, 5);
        jpanContent.add(createProjectButton, gbc);
    }

    /**
     * @noinspection ALL
     */
    public JComponent $$$getRootComponent$$$() {
        return jpanContent;
    }
}
